package com.nsu.konus.control.commands;

import java.util.HashMap;

/**
 * @author Strot
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
public class ControlChars {
	
	public static final char ESCAPE = 1;
	
	public static final char BACKSPACE = 14;
	
	public static final char TAB = 15;
	
	public static final char ENTER = 28;
	
	public static final char LCTRL = 29;
	
	public static final char LSHIFT = 42;
	
	public static final char RSHIFT = 54;
	
	public static final char F1 = 59;
	
	public static final char F2 = 60;
	
	public static final char F3 = 61;
	
	public static final char F4 = 62;
	
	public static final char F5 = 63;
	
	public static final char F6 = 64;
	
	public static final char F7 = 65;
	
	public static final char F8 = 66;
	
	public static final char F9 = 67;
	
	public static final char F10 = 68;
	
	public static final char F11 = 87;
	
	public static final char F12 = 88;
	
	public static final char PAGEUP = 201;
	
	public static final char PAGEDOWN = 209;
	
	public static final char LEFT = 203;
	
	public static final char RIGHT = 205;
	
	public static final char DOWN = 208;
	
	public static final char UP = 200;
	
	private static IntHashMap symbolMap;
	
	private static HashMap nameMap;
	
	public static ControlSymbol getSymbol(char c) {
		if (symbolMap == null)
			init();
		Object o = symbolMap.get(c);
		if (o == null)
			throw new IllegalArgumentException("Cann't find char number " + (int)c);
		return (ControlSymbol)o;
	}
	
	private static void init() {
		initSymbolMap();
		initNameSymbols();
	}
	
	private static void initSymbolMap(){
		symbolMap = new IntHashMap(256);
		char analog;
		// {1} -> escape
		analog = 2;
		addTwoSymbols('1', '!', analog++);
		addTwoSymbols('2', '@', analog++);
		addTwoSymbols('3', '#', analog++);
		addTwoSymbols('4', '$', analog++);
		addTwoSymbols('5', '%', analog++);
		addTwoSymbols('6', '^', analog++);
		addTwoSymbols('7', '&', analog++);
		addTwoSymbols('8', '*', analog++);
		addTwoSymbols('9', '(', analog++);
		addTwoSymbols('0', ')', analog++);
		addTwoSymbols('-', '_', analog++);
		addTwoSymbols('=', '+', analog++);
		//analog = 14
		// {14} -> backspace
		// {15} -> tab
		
		analog = 16;
		addTwoSymbols('q', 'Q', analog++);
		addTwoSymbols('w', 'W', analog++);
		addTwoSymbols('e', 'E', analog++);
		addTwoSymbols('r', 'R', analog++);
		addTwoSymbols('t', 'T', analog++);
		addTwoSymbols('y', 'Y', analog++);
		addTwoSymbols('u', 'U', analog++);
		addTwoSymbols('i', 'I', analog++);
		addTwoSymbols('o', 'O', analog++);
		addTwoSymbols('p', 'P', analog++);
		addTwoSymbols('[', '{', analog++);
		addTwoSymbols(']', '}', analog++);
		//analog = 28
		// {28} -> enter
		// {29} -> left ctrl
		
		analog = 30;
		addTwoSymbols('a', 'A', analog++);
		addTwoSymbols('s', 'S', analog++);
		addTwoSymbols('d', 'D', analog++);
		addTwoSymbols('f', 'F', analog++);
		addTwoSymbols('g', 'G', analog++);
		addTwoSymbols('h', 'H', analog++);
		addTwoSymbols('j', 'J', analog++);
		addTwoSymbols('k', 'K', analog++);
		addTwoSymbols('l', 'L', analog++);
		addTwoSymbols(';', ':', analog++);
		addTwoSymbols("'".charAt(0), '"', analog++);
		addTwoSymbols('`', '~', analog++);
		//analog = 42
		// {42} -> left shift
		addTwoSymbols('\\', '|', (char)43);
		
		analog = 44;
		addTwoSymbols('z', 'Z', analog++);
		addTwoSymbols('x', 'X', analog++);
		addTwoSymbols('c', 'C', analog++);
		addTwoSymbols('v', 'V', analog++);
		addTwoSymbols('b', 'B', analog++);
		addTwoSymbols('n', 'N', analog++);
		addTwoSymbols('m', 'M', analog++);
		addTwoSymbols(',', '<', analog++);
		addTwoSymbols('.', '>', analog++);
		addTwoSymbols('/', '?', analog++);
		//analog = 54
		
		symbolMap.put(' ', new ControlSymbol((char)57, false));
	}
	
	private static void initNameSymbols() {
		nameMap = new HashMap(256);
		
		addNameSymbol("esc", 1);
		addNameSymbol("backspace", 14);
		addNameSymbol("tab", 15);
		addNameSymbol("enter", 28);
		addNameSymbol("lctrl", 29);
		addNameSymbol("lshift", 42);
		addNameSymbol("rshift", 54);
		addNameSymbol("f1", 59);
		addNameSymbol("f2", 60);
		addNameSymbol("f3", 61);
		addNameSymbol("f4", 62);
		addNameSymbol("f5", 63);
		addNameSymbol("f6", 64);
		addNameSymbol("f7", 65);
		addNameSymbol("f8", 66);
		addNameSymbol("f9", 67);
		addNameSymbol("f10", 68);
		addNameSymbol("f11", 87);
		addNameSymbol("f12", 88);
		addNameSymbol("pageup", 201);
		addNameSymbol("pagedown", 209);
		addNameSymbol("left", 203);
		addNameSymbol("right", 205);
		addNameSymbol("down", 208);
		addNameSymbol("up", 200);
	}
	
	private static void addTwoSymbols(char s1, char s2, char analog) {
		symbolMap.put(s1, new ControlSymbol(analog, false));
		symbolMap.put(s2, new ControlSymbol(analog, true));
	}
	
	private static void addNameSymbol(String name, char s) {
		nameMap.put(name, new ControlSymbol(s, false));
	}
	
	private static void addNameSymbol(String name, int s) {
		addNameSymbol(name, (char)s);
	}
	
}
